home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Tools / glimpse-2.1 / index / glimpse.c < prev    next >
C/C++ Source or Header  |  1995-05-16  |  22KB  |  670 lines

  1. /* Copyright (c) 1994 Sun Wu, Udi Manber, Burra Gopal.  All Rights Reserved. */
  2. /* ./glimpse/index/glimpse.c */
  3. #include "glimpse.h"
  4. #include <stdlib.h>
  5.  
  6. extern char **environ;
  7. extern int errno;
  8. #if    BG_DEBUG
  9. extern FILE  *LOGFILE;     /* file descriptor for LOG output */
  10. #endif    /*BG_DEBUG*/
  11. extern FILE  *STATFILE;    /* file descriptor for statistical data about indexed files */
  12. extern FILE  *MESSAGEFILE;    /* file descriptor for important messages meant for the user */
  13. extern char  INDEX_DIR[MAX_LINE_LEN];
  14. extern struct stat istbuf;
  15.  
  16. extern int indexable_char[256];
  17. extern int OneFilePerBlock;
  18. extern int IndexNumber;
  19. extern int CountWords;
  20. extern int StructuredIndex;
  21. extern int MAXWORDSPERFILE;
  22. extern int NUMERICWORDPERCENT;
  23. extern int AddToIndex;
  24. extern int FastIndex;
  25. extern int BuildDictionary;
  26. extern int BuildDictionaryExisting;
  27. extern int CompressAfterBuild;
  28. extern int IncludeHigherPriority;
  29. extern int FilenamesOnStdin;
  30. extern int UseFilters;
  31. extern int ByteLevelIndex;
  32. /* extern int IndexUnderscore; */
  33. extern int IndexableFile;
  34. extern int MAX_PER_MB, MAX_INDEX_PERCENT;
  35.  
  36. extern int AddedMaxWordsMessage;
  37. extern int AddedMixedWordsMessage;
  38.  
  39. extern int file_num;
  40. extern int file_id;
  41. extern int part_num;
  42. extern char *name_list[MAX_LIST];
  43. extern int p_table[MAX_PARTITION];
  44. extern int  *size_list;
  45. extern int p_size_list[];
  46. extern int disable_list[FILEMASK_SIZE];
  47. extern int memory_usage;
  48. extern int mask_int[];
  49.  
  50. extern set_usemalloc();    /* compress/misc.c */
  51.  
  52. char IProgname[MAX_LINE_LEN];
  53.  
  54. /*
  55.  * Has newnum crossed the boundary of an encoding? This is so rare that we
  56.  * needn't optimize it by changing the format of the old index and reusing it.
  57.  */
  58. cross_boundary(oldnum, newnum)
  59.     int    oldnum, newnum;
  60. {
  61.     int    ret;
  62.  
  63.     if (oldnum <= 0) return 0;
  64.     ret =  ( ((oldnum <= MaxNum8bPartition) && (newnum > MaxNum8bPartition)) ||
  65.          ((oldnum <= MaxNum12bPartition) && (newnum > MaxNum12bPartition)) ||
  66.          ((oldnum <= MaxNum16bPartition) && (newnum > MaxNum16bPartition)) );
  67.     if (ret) fprintf(MESSAGEFILE, "Must change index format. Commencing fresh indexing...\n");
  68.     return ret;
  69. }
  70.  
  71. main(argc, argv)
  72. int argc;
  73. char **argv;
  74. {
  75.     int pid = getpid();
  76.     int    i;
  77.     char *indexdir;
  78.     char s[MAX_LINE_LEN];
  79.     char working_dir[MAX_LINE_LEN];
  80.     FILE *tmpfp;
  81.     char hash_file[MAX_LINE_LEN], string_file[MAX_LINE_LEN], freq_file[MAX_LINE_LEN];
  82.     char tmpbuf[1024];
  83.     struct stat stbuf;
  84.     char name[MAX_LINE_LEN];
  85.     char outname[MAX_LINE_LEN];
  86.     int specialwords, threshold;
  87.     int backup;
  88.  
  89.     BuildDictionary = ON;
  90.     set_usemalloc();
  91.     srand(pid);
  92.     umask(077);
  93.  
  94.     INDEX_DIR[0] = '\0';
  95.     specialwords = threshold = -1;    /* so that compute_dictionary can use defaults not visible here */
  96.     strncpy(IProgname, argv[0], MAX_LINE_LEN);
  97.     memset(disable_list, '\0', sizeof(int) * FILEMASK_SIZE);    /* nothing is disabled initially */
  98.     size_list = (int *)malloc(sizeof(int) * MAX_LIST);
  99.     memset(size_list, '\0', sizeof(int) * MAX_LIST);    /* free it once partition successfully calculates p_size_list */
  100.     memset(p_size_list, '\0', sizeof(int) * MAX_PARTITION);
  101.  
  102.  
  103.     /*
  104.      * Process options.
  105.      */
  106.  
  107.     while (argc > 1) {
  108.     if (strcmp(argv[1], "-help") == 0) {
  109.         return usage(1);
  110.     }
  111. #if    !BUILDCAST
  112.     else if (strcmp(argv[1], "-V") == 0) {
  113.         printf("\nThis is glimpseindex version %s, %s.\n\n", GLIMPSE_VERSION, GLIMPSE_DATE);
  114.         return(0);
  115.     }
  116.     else if (strcmp(argv[1], "-I") == 0) {
  117.         IndexableFile = ON;
  118.         argc --; argv ++;
  119.     }
  120.     else if(strcmp(argv[1], "-a") == 0) {
  121.         AddToIndex = ON;
  122.         argc--; argv++;
  123.     }
  124.     else if(strcmp(argv[1], "-b") == 0) {
  125.         ByteLevelIndex = ON;
  126.         argc--; argv++;
  127.     }
  128.     else if(strcmp(argv[1], "-c") == 0) {
  129.         CountWords = ON;
  130.         argc--; argv++;
  131.     }
  132.     else if(strcmp(argv[1], "-f") == 0) {
  133.         FastIndex = ON;
  134.         argc--; argv++;
  135.     }
  136.     else if (strcmp(argv[1], "-o") == 0) {
  137.         OneFilePerBlock = ON;
  138.         argc --; argv ++;
  139.     }
  140.     else if (strcmp(argv[1], "-s") == 0) {
  141.         StructuredIndex = ON;
  142.         argc --; argv ++;
  143.     }
  144.     else if(strcmp(argv[1], "-z") == 0) {
  145.         UseFilters = ON;
  146.         argc--; argv++;
  147.     }
  148. #else    /*!BUILDCAST*/
  149.     else if (strcmp(argv[1], "-V") == 0) {
  150.         printf("\nThis is buildcast version %s, %s.\n\n", GLIMPSE_VERSION, GLIMPSE_DATE);
  151.         return(0);
  152.     }
  153.     else if(strcmp(argv[1], "-C") == 0) {
  154.         CompressAfterBuild = ON;
  155.         argc --; argv ++;
  156.     }
  157.     else if(strcmp(argv[1], "-E") == 0) {
  158.         BuildDictionaryExisting = ON;
  159.         argc --; argv ++;
  160.     }
  161.     else if (strcmp(argv[1], "-t") == 0) {
  162.         if ((argc <= 2) || !(isdigit(argv[2][0]))) {
  163.         return usage(1);
  164.         }
  165.         else {
  166.         threshold = atoi(argv[2]);
  167.         argc -= 2; argv += 2;
  168.         }
  169.     }
  170.     else if (strcmp(argv[1], "-l") == 0) {
  171.         if ((argc <= 2) || !(isdigit(argv[2][0]))) {
  172.         return usage(1);
  173.         }
  174.         else {
  175.         specialwords = atoi(argv[2]);
  176.         argc -= 2; argv += 2;
  177.         }
  178.     }
  179. #endif    /*!BUILDCAST*/
  180.     else if (strcmp(argv[1], "-w") == 0) {
  181.         if (argc == 2) {
  182.         fprintf(stderr, "-w should be followed by the number of words\n");
  183.         return usage(1);
  184.         }
  185.         MAXWORDSPERFILE = atoi(argv[2]);
  186.         argc -= 2; argv += 2;
  187.     }
  188.     else if (strcmp(argv[1], "-S") == 0) {
  189.         if (argc == 2) {
  190.         fprintf(stderr, "-S should be followed by the stop list limit\n");
  191.         return usage(1);
  192.         }
  193.         MAX_PER_MB = MAX_INDEX_PERCENT = atoi(argv[2]);
  194.         argc -= 2; argv += 2;
  195.     }
  196.     else if(strcmp(argv[1], "-n") == 0) {
  197.         IndexNumber = ON;
  198.         if ((argc <= 2) || !(isdigit(argv[2][0]))) {    /* -n has no arg */
  199.         argc --; argv ++;
  200.         }
  201.         else {
  202.         NUMERICWORDPERCENT = atoi(argv[2]);
  203.         if ((NUMERICWORDPERCENT > 100) || (NUMERICWORDPERCENT < 0)) {
  204.             fprintf(stderr, "The percentage of numeric words must be in [0..100]\n");
  205.             return usage(1);
  206.         }
  207.         argc-=2; argv+=2;
  208.         }
  209.     }
  210.     else if(strcmp(argv[1], "-i") == 0) {
  211.         IncludeHigherPriority = ON;
  212.         argc --; argv ++;
  213.     }
  214.     else if(strcmp(argv[1], "-F") == 0) {
  215.         FilenamesOnStdin = ON;
  216.         argc--; argv++;
  217.     }
  218.     /*
  219.     else if(strcmp(argv[1], "-u") == 0) {
  220.         IndexUnderscore = ON;
  221.         argc--; argv++;
  222.     }
  223.     */
  224.     else if (strcmp(argv[1], "-H") == 0) {
  225.         if (argc == 2) {
  226.         fprintf(stderr, "-H should be followed by a directory name\n");
  227.         return usage(1);
  228.         }
  229.         strncpy(INDEX_DIR, argv[2], MAX_LINE_LEN);
  230.         argc -= 2; argv += 2;
  231.     }
  232.     else break;    /* rest are directory names */
  233.     }
  234.  
  235.     /*
  236.      * Look for invalid option combos.
  237.      */
  238.  
  239.     if ((argc<=1) && (!FilenamesOnStdin)) {
  240.     return usage(1);
  241.     }
  242.  
  243.     if (ByteLevelIndex) {
  244.     if (MAX_PER_MB <= 0) {
  245.         fprintf(stderr, "Stop list limit (#of occurrences per MB) '%d' must be > 0\n", MAX_PER_MB);
  246.         exit(2);
  247.     }
  248.     }
  249.     else if (OneFilePerBlock) {
  250.     if ((MAX_INDEX_PERCENT <= 0) || (MAX_INDEX_PERCENT > 100)) {
  251.         fprintf(stderr, "Stop list limit (%% of occurrences in files) '%d' must be in (0, 100]\n", MAX_INDEX_PERCENT);
  252.         exit(2);
  253.     }
  254.     }
  255.  
  256.     /*
  257.      * Find the index directory since it is used in all options.
  258.      */
  259.  
  260.     if (INDEX_DIR[0] == '\0') {
  261.     if ((indexdir = getenv("HOME")) == NULL) {
  262.         getcwd(INDEX_DIR, MAX_LINE_LEN-1);
  263.         fprintf(stderr, "Using working-directory '%s' to store index\n\n", INDEX_DIR);
  264.     }
  265.     else strncpy(INDEX_DIR, indexdir, MAX_LINE_LEN);
  266.     }
  267.     getcwd(working_dir, MAX_LINE_LEN - 1);
  268.     if (-1 == chdir(INDEX_DIR)) {
  269.     fprintf(stderr, "Cannot change directory to %s\n", INDEX_DIR);
  270.     return usage(0);
  271.     }
  272.     getcwd(INDEX_DIR, MAX_LINE_LEN - 1);    /* must be absolute path name */
  273.     chdir(working_dir);    /* get back to where you were */
  274.  
  275.     if (IndexableFile) {    /* traverse the given directories and output names of files that are indexable on stdout */
  276.     partition(argc, argv);
  277.     return 0;
  278.     }
  279.     else {
  280. #if    BUILDCAST
  281.     printf("\nThis is buildcast version %s, %s.\n\n", GLIMPSE_VERSION, GLIMPSE_DATE);
  282. #else    /*BUILDCAST*/
  283.     printf("\nThis is glimpseindex version %s, %s.\n\n", GLIMPSE_VERSION, GLIMPSE_DATE);
  284. #endif    /*BUILDCAST*/
  285.     }
  286.  
  287.     if (ByteLevelIndex) {
  288.     /* We'll worry about these things later */
  289.     if (AddToIndex || FastIndex) {
  290.         fprintf(stderr, "Fresh indexing recommended: -a and -f are not supported with -b as yet\n");
  291.         exit(1);
  292.     }
  293.     CountWords = AddToIndex = FastIndex = OFF;
  294.     OneFilePerBlock = ON;
  295.     }
  296.  
  297.     /*
  298.      * CONVENTION: all the relevant output is on stdout; warnings/errors are on stderr.
  299.      * Initialize / open important files.
  300.      */
  301.  
  302.     read_filters(INDEX_DIR, UseFilters);
  303.  
  304.     freq_file[0] = hash_file[0] = string_file[0] = '\0';
  305.     strcpy(freq_file, INDEX_DIR);
  306.     strcat(freq_file, "/");
  307.     strcat(freq_file, DEF_FREQ_FILE);
  308.     strcpy(hash_file, INDEX_DIR);
  309.     strcat(hash_file, "/");
  310.     strcat(hash_file, DEF_HASH_FILE);
  311.     strcpy(string_file, INDEX_DIR);
  312.     strcat(string_file, "/");
  313.     strcat(string_file, DEF_STRING_FILE);
  314.     initialize_tuncompress(string_file, freq_file, 0);
  315.  
  316. #if    BG_DEBUG
  317.     sprintf(s, "%s/%s", INDEX_DIR, DEF_LOG_FILE);
  318.     if((LOGFILE = fopen(s, "w")) == 0) {
  319.     fprintf(stderr, "can't open %s for writing\n", s);
  320.     LOGFILE = stderr;
  321.     }
  322. #endif    /*BG_DEBUG*/
  323.  
  324.     sprintf(s, "%s/%s", INDEX_DIR, DEF_MESSAGE_FILE);
  325.     if((MESSAGEFILE = fopen(s, "w")) == 0) {
  326.     fprintf(stderr, "can't open %s for writing\n", s);
  327.     MESSAGEFILE = stderr;
  328.     }
  329.  
  330.     sprintf(s, "%s/%s", INDEX_DIR, DEF_STAT_FILE);
  331.     if((STATFILE = fopen(s, "w")) == 0) {
  332.     fprintf(stderr, "can't open %s for writing\n", s);
  333.     STATFILE = stderr;
  334.     }
  335.  
  336. #if    BG_DEBUG
  337.     fprintf(LOGFILE, "Index Directory = %s\n\n", INDEX_DIR);
  338. #endif    /*BG_DEBUG*/
  339.     if (MAXWORDSPERFILE != 0) fprintf(MESSAGEFILE, "Index: maximum number of indexed words per file = %d\n", MAXWORDSPERFILE);
  340.     else fprintf(MESSAGEFILE, "Index: maximum number of indexed words per file = infinity\n");
  341.     fprintf(MESSAGEFILE, "Index: maximum percentage of numeric words per file = %d\n", NUMERICWORDPERCENT);
  342.  
  343.     set_indexable_char(indexable_char);
  344.  
  345. #if    BUILDCAST
  346.  
  347.     CountWords = ON;
  348.     AddToIndex = OFF;
  349.     FastIndex = OFF;
  350.  
  351.     /* Save old search-dictionaries */
  352.  
  353.     sprintf(s, "%s/.glimpse_index", INDEX_DIR);
  354.     if (!access(s, R_OK)) {
  355.     sprintf(s, "%s/.glimpse_tempdir.%d", INDEX_DIR, pid);
  356.     if (-1 == mkdir(s, 0700)) {
  357.         fprintf(stderr, "cannot create temporary directory %s\n", s);
  358.         return -1;
  359.     }
  360.     sprintf(s, "mv -f %s/.glimpse_index %s/.glimpse_tempdir.%d\n", INDEX_DIR, INDEX_DIR, pid);
  361.     system(s);
  362.     sprintf(s, "mv -f %s/.glimpse_partitions %s/.glimpse_tempdir.%d\n", INDEX_DIR, INDEX_DIR, pid);
  363.     system(s);
  364.     sprintf(s, "mv -f %s/.glimpse_filenames %s/.glimpse_tempdir.%d\n", INDEX_DIR, INDEX_DIR, pid);
  365.     system(s);
  366.     sprintf(s, "mv -f %s/.glimpse_statistics %s/.glimpse_tempdir.%d\n", INDEX_DIR, INDEX_DIR, pid);
  367.     system(s);
  368.     /* Don't save messages, log, debug, etc. */
  369.     sprintf(s, "%s/.glimpse_attributes", INDEX_DIR);
  370.     if (!access(s, R_OK)) {
  371.         sprintf(s, "mv -f %s/.glimpse_attributes %s/.glimpse_tempdir.%d\n", INDEX_DIR, INDEX_DIR, pid);
  372.         system(s);
  373.     }
  374.     }
  375.  
  376.     /* Backup old cast-dictionaries: don't use move since indexing might want to use them */
  377.     sprintf(s, "%s/.glimpse_quick", INDEX_DIR);
  378.     if (!access(s, R_OK)) {    /* there are previous cast dictionaries */
  379.     backup = rand();
  380.     sprintf(s, "%s/.glimpse_backup.%x", INDEX_DIR, backup);
  381.     if (-1 == mkdir(s, 0700)) {
  382.         fprintf(stderr, "cannot create backup directory %s\n", s);
  383.         return -1;
  384.     }
  385.     sprintf(s, "cp %s/.glimpse_quick %s/.glimpse_backup.%x\n", INDEX_DIR, INDEX_DIR, backup);
  386.     system(s);
  387.     sprintf(s, "cp %s/.glimpse_compress %s/.glimpse_backup.%x\n", INDEX_DIR, INDEX_DIR, backup);
  388.     system(s);
  389.     sprintf(s, "cp %s/.glimpse_compress.index %s/.glimpse_backup.%x\n", INDEX_DIR, INDEX_DIR, backup);
  390.     system(s);
  391.     sprintf(s, "cp %s/.glimpse_uncompress %s/.glimpse_backup.%x\n", INDEX_DIR, INDEX_DIR, backup);
  392.     system(s);
  393.     sprintf(s, "cp %s/.glimpse_uncompress.index %s/.glimpse_backup.%x\n", INDEX_DIR, INDEX_DIR, backup);
  394.     system(s);
  395.     printf("Saved previous cast-dictionary in %s/.glimpse_backup.%x\n", INDEX_DIR, backup);
  396.     }
  397.  
  398.     /* Now index these files, and build new dictionaries */
  399.     partition(argc, argv);
  400.     destroy_filename_hashtable();
  401.     if (size_list != NULL) free(size_list);
  402.     size_list = NULL;
  403.     build_index();
  404.  
  405.     cleanup();
  406.     save_data_structures();
  407.     uninitialize_common();
  408.     uninitialize_tcompress();
  409.     uninitialize_tuncompress();
  410.     compute_dictionary(threshold, DISKBLOCKSIZE, specialwords, INDEX_DIR);
  411.  
  412.     if (CompressAfterBuild) {
  413.     /* For the new compression */
  414.     if (!initialize_tcompress(hash_file, freq_file, TC_ERRORMSGS)) goto docleanup;
  415.     printf("Compressing files with new dictionary...\n");
  416.     /* Use the set of file-names collected during partition() / modified during build_hash */
  417.     for(i=0; i<file_num; i++) {
  418.         if (disable_list[block2index(i)] & mask_int[i%(8*sizeof(int))]) continue;
  419.         strcpy(name, name_list[i]);
  420.         tcompress_file(name, outname, TC_REMOVE | TC_EASYSEARCH | TC_OVERWRITE | TC_NOPROMPT);
  421.     }
  422.     }
  423.  
  424. docleanup:
  425.     /* Restore old search-dictionaries */
  426.     sprintf(s, "%s/.glimpse_tempdir.%d/.glimpse_index", INDEX_DIR, pid);
  427.     if (!access(s, R_OK)) {
  428.     sprintf(s, "mv -f %s/.glimpse_tempdir.%d/.glimpse_* %s\n", INDEX_DIR, pid, INDEX_DIR);
  429.     system(s);
  430.     sprintf(s, "%s/.glimpse_tempdir.%d", INDEX_DIR, pid);
  431.     rmdir(s);
  432.     }
  433.     printf("\nBuilt new cast-dictionary in %s\n", INDEX_DIR);
  434.  
  435. #else    /*BUILDCAST*/
  436.  
  437.     if (AddToIndex || FastIndex) {
  438.     /* Not handling byte level indices here for now */
  439.     int    indextype;
  440.  
  441.     sprintf(s, "%s/%s", INDEX_DIR, INDEX_FILE);
  442.     if (-1 == stat(s, &istbuf)) {
  443.         if (AddToIndex) {
  444.         fprintf(stderr, "Cannot find previous index! Fresh indexing recommended\n", s);
  445.         return usage(0);
  446.         }
  447.         file_num = 0;
  448.         file_id = 0;
  449.         part_num = 1;
  450.         goto fresh_indexing;
  451.     }
  452.  
  453.     /* Find out existing index of words and partitions/filenumbers */
  454.     if ((indextype = get_index_type(s)) < 0) {
  455.         fprintf(stderr, "Fresh indexing recommended: -a and -f are not supported with -b as yet\n");
  456.         exit(1);
  457.     }
  458.     file_num = part_num = 0;
  459.     sprintf(s, "%s/%s", INDEX_DIR, NAME_LIST);
  460.     file_num = get_array_of_lines(s, name_list, MAX_LIST, 1);
  461.     if (!indextype) {
  462.         sprintf(s, "%s/%s", INDEX_DIR, P_TABLE);
  463.         part_num = get_table(s, p_table, MAX_PARTITION, 1) - 1;    /* part_num INCLUDES last partition */
  464.     }
  465.     else merge_splits();    /* Is never called at present for ByteLevelIndex since each build is from scratch. MUST HANDLE LATER */
  466.  
  467.     /* Check for errors, Set OneFilePerBlock */
  468.     if ( (file_num <= 0) || (!indextype && (part_num <= 0)) ) {
  469.         if (AddToIndex) {
  470.         fprintf(stderr, "Cannot find previous glimpseindex files! Fresh indexing recommended\n");
  471.         return usage(0);
  472.         }
  473.         file_num = 0;
  474.         file_id = 0;
  475.         part_num = 1;
  476.         goto fresh_indexing;
  477.     }
  478.     if (OneFilePerBlock && !indextype) {
  479.         fprintf(stderr, "Warning: ignoring option -o: using format of existing index\n");
  480.     }
  481.     OneFilePerBlock = indextype;
  482.  
  483.     /* Used in FastIndex for all existing files, used in AddToIndex if we are trying to add an existing file */
  484.     build_filename_hashtable(name_list, file_num);
  485.  
  486. #if    0
  487.     /* Test if these are inverses of each other */
  488.     save_data_structures();
  489.     merge_splits();
  490. #endif    /*0*/
  491.  
  492.     /*
  493.      * FastIndex: set disable-flag for unchanged files: remove AND
  494.      * disable non-existent files. Let hole remain in file-names/partitions.
  495.      */
  496.     if (FastIndex) {
  497.         for (i=0; i<file_num; i++)
  498.         if (-1 == stat(name_list[i], &stbuf)) {
  499.             remove_filename(i, -1);
  500.         }
  501.         else if (((stbuf.st_mode & S_IFMT) == S_IFREG) && (stbuf.st_ctime <= istbuf.st_ctime)) {
  502.             /* This is just used as a cache since exclude/include processing is not done here: see dir.c */
  503.             disable_list[block2index(i)] |= mask_int[i % (8*sizeof(int))];
  504.         }
  505.         else {
  506.             /* Can't do it for directories since files in it can be modified w/o date reflected in the directory. Same for symlinks. */
  507.             size_list[i] = stbuf.st_size;
  508.             disable_list[block2index(i)] &= ~(mask_int[i % (8*sizeof(int))]);
  509.         }
  510.     }
  511.     /*
  512.      * AddToIndex: disable all existing files, remove those that don't exist now.
  513.      * Out of old ones, only ADDED FILES are re-enabled: dir.c
  514.      */
  515.     else {
  516.         for (i=0; i<file_num; i++) {
  517.         if (-1 == stat(name_list[i], &stbuf)) {
  518.             remove_filename(i, -1);
  519.         }
  520.         else {
  521.             size_list[i] = stbuf.st_size;    /* ONLY for proper statistics in save_data_structures() */
  522.             disable_list[block2index(i)] |= mask_int[i % (8*sizeof(int))];
  523.         }
  524.         }
  525.     }
  526.  
  527.     /* Put old/new files into partitions/filenumbers */
  528.     if (-1 == oldpartition(argc, argv)) {
  529.         for(i=0;i<file_num;i++) {
  530. #if    BG_DEBUG
  531.         memory_usage -= (strlen(name_list[i]) + 2);
  532. #endif    /*BG_DEBUG*/
  533.         if (name_list[i] != NULL) my_free(name_list[i], 0);
  534.         name_list[i] = NULL;
  535.         }
  536.         memset(disable_list, '\0', sizeof(int) * FILEMASK_SIZE);
  537.         file_num = 0;
  538.         file_id = 0;
  539.         for (i=0;i<part_num; i++) {
  540.         p_table[i] = 0;
  541.         }
  542.         part_num = 1;
  543.         destroy_filename_hashtable();
  544.         goto fresh_indexing;
  545.     }
  546.  
  547.     /* Reindex all the files but use the file-names obtained with oldpartition() */
  548.     if (cross_boundary(OneFilePerBlock, file_num)) {
  549.         memset(disable_list, '\0', sizeof(int) * FILEMASK_SIZE);
  550.     }
  551.  
  552.     if (size_list != NULL) free(size_list);
  553.     size_list = NULL;
  554.     build_index();
  555.     destroy_filename_hashtable();
  556. #if    BG_DEBUG
  557.     fprintf(LOGFILE, "Built indices in %s/%s\n", INDEX_DIR, INDEX_FILE);
  558. #endif    /*BG_DEBUG*/
  559.     goto docleanup;
  560.     }
  561.  
  562. fresh_indexing:
  563.     /* These should be zeroed since they can confuse fsize and fsize_directory() */
  564.     AddToIndex = 0;
  565.     FastIndex = 0;
  566. #if    BG_DEBUG
  567.     fprintf(LOGFILE, "Commencing fresh indexing\n");
  568. #endif    /*BG_DEBUG*/
  569.     partition(argc, argv);
  570.     destroy_filename_hashtable();
  571.     if (size_list != NULL) free(size_list);
  572.     size_list != NULL;
  573.     build_index();
  574. #if    BG_DEBUG
  575.     fprintf(LOGFILE, "\nBuilt indices in %s/%s\n", INDEX_DIR, INDEX_FILE);
  576. #endif    /*BG_DEBUG*/
  577.  
  578. docleanup:
  579.     cleanup();
  580.     save_data_structures();
  581. #if    BG_DEBUG
  582.     fflush(LOGFILE);
  583.     fclose(LOGFILE);
  584. #endif    /*BG_DEBUG*/
  585.     fflush(MESSAGEFILE);
  586.     fclose(MESSAGEFILE);
  587.     fflush(STATFILE);
  588.     fclose(STATFILE);
  589.     if (AddedMaxWordsMessage) printf("\nSome files contributed > %d words to the index: check %s\n", MAXWORDSPERFILE, DEF_MESSAGE_FILE);
  590.     if (AddedMixedWordsMessage) printf("Some files had numerals in > %d%% of the indexed words: check %s\n", NUMERICWORDPERCENT, DEF_MESSAGE_FILE);
  591.  
  592.     printf("\nIndex-directory: \"%s\"\nGlimpse-files created here:\n", INDEX_DIR);
  593.     chdir(INDEX_DIR);
  594.     sprintf(s, "ls -lg .glimpse_* > /tmp/%d\n", pid);
  595.     system(s);
  596.     sprintf(s, "/tmp/%d", pid);
  597.     if ((tmpfp = fopen(s, "r")) != NULL) {
  598.     memset(tmpbuf, '\0', 1024);
  599.     while(fgets(tmpbuf, 1024, tmpfp) != NULL) fputs(tmpbuf, stdout);
  600.     fflush(tmpfp);
  601.     fclose(tmpfp);
  602.     unlink(s);
  603.     }
  604.     else fprintf(stderr, "cannot open %s to `cat': check %s for .glimpse - files\n", s, INDEX_DIR);
  605. #endif    /*BUILDCAST*/
  606.  
  607.     return 0;
  608. }
  609.  
  610. cleanup()
  611. {
  612.     char s[MAX_LINE_LEN];
  613.  
  614.     sprintf(s, "%s/%s", INDEX_DIR, I1);
  615.     unlink(s);
  616.     sprintf(s, "%s/%s", INDEX_DIR, I2);
  617.     unlink(s);
  618.     sprintf(s, "%s/%s", INDEX_DIR, I3);
  619.     unlink(s);
  620.     sprintf(s, "%s/%s", INDEX_DIR, O1);
  621.     unlink(s);
  622.     sprintf(s, "%s/%s", INDEX_DIR, O2);
  623.     unlink(s);
  624.     sprintf(s, "%s/%s", INDEX_DIR, O3);
  625.     unlink(s);
  626.     sprintf(s, "%s/.glimpse_apply.%d", INDEX_DIR, getpid());
  627.     unlink(s);
  628. }
  629.  
  630. #if    !BUILDCAST
  631. usage(flag)
  632. int    flag;
  633. {
  634.     if (flag) fprintf(stderr, "\nThis is glimpseindex version %s, %s.\n\n", GLIMPSE_VERSION, GLIMPSE_DATE);
  635.     fprintf(stderr, "usage: %s [-help] [-a] [-f] [-i] [-n [#]] [-o] [-s] [-w #] [-F] [-H dir] [-I] [-S lim] [-V] dirs/files\n", IProgname);
  636.         fprintf(stderr, "summary of frequently used options\n(for a more detailed listing see 'man glimpse'):\n");
  637.     fprintf(stderr, "-help: outputs this menu\n");
  638.         fprintf(stderr, "-a: add given files/dirs to an existing index\n");
  639.     fprintf(stderr, "-b: build a (large) byte level index to speed up search\n");
  640.         fprintf(stderr, "-f: use modification dates to do fast indexing\n");
  641.         fprintf(stderr, "-n #: index numbers; warn if file adds > #%% numeric words: default is 50\n");
  642.         fprintf(stderr, "-o: optimize for speed by building a larger index\n");
  643.     /* fprintf(stderr, "-s: build the index for structured queries (a1=v1 &/| a2=v2...)\n"); this should not be advertised */
  644.         fprintf(stderr, "-w #: warn if a file adds > # words to the index\n");
  645.     fprintf(stderr, "-F: expect filenames on stdin (useful for pipelining)\n");
  646.         fprintf(stderr, "-H 'dir': .glimpse-files should be in directory 'dir': default is '~'\n");
  647.     fprintf(stderr, "\n");
  648.     fprintf(stderr, "For questions about glimpse, please contact `%s'\n", GLIMPSE_EMAIL);
  649.     exit(1);
  650. }
  651. #else    /*!BUILDCAST*/
  652. usage(flag)
  653. int    flag;
  654. {
  655.     if (flag) fprintf(stderr, "\nThis is buildcast version %s, %s.\n\n", GLIMPSE_VERSION, GLIMPSE_DATE);
  656.     fprintf(stderr, "usage: %s [-help] [-t] [-i] [-l] [-n [#]] [-w #] [-C] [-E] [-F] [-H dir] [-V] dirs/files\n", IProgname);
  657.         fprintf(stderr, "summary of frequently used options\n(for a more detailed listing see 'man cast'):\n");
  658.     fprintf(stderr, "-help: output this menu\n");
  659.         fprintf(stderr, "-n #: index numbers; warn if file adds > #%% numeric words: default is 50\n");
  660.         fprintf(stderr, "-w #: warn if a file adds > # words to the index\n");
  661.     fprintf(stderr, "-C: compress files with the new dictionary after building it\n");
  662.     fprintf(stderr, "-E: build cast dictionary using existing compressed files only\n");
  663.     fprintf(stderr, "-F: expect filenames on stdin (useful for pipelining)\n");
  664.         fprintf(stderr, "-H 'dir': .glimpse-files should be in directory 'dir': default is '~'\n");
  665.     fprintf(stderr, "\n");
  666.     fprintf(stderr, "For questions about glimpse, please contact `%s'\n", GLIMPSE_EMAIL);
  667.     exit(1);
  668. }
  669. #endif    /*!BUILDCAST*/
  670.